#ifndef CHANNEL_HPP
#define CHANNEL_HPP

#include "InetAddr.hpp"
#include "Connection.hpp"
#include "Reactor.hpp"

class Reactor; // 前向声明
// 普通sockfd的封装
class Channel : public Connection
{
    static constexpr int SIZE = 1024;

public:
    Channel(const int sockfd, const InetAddr client_addr)
        : _sockfd(sockfd), _client_addr(client_addr)
    {
        // 设置非阻塞
        setNonBlock(_sockfd);
    }

    void HandleRead() override
    {
        char buffer[SIZE];
        // 循环读取
        while (true)
        {
            // 强制清空残留数据，防止污染本次读取
            buffer[0] = 0;
            // 设置阻塞读
            ssize_t recv_len = recv(_sockfd, buffer, sizeof(buffer) - 1, 0);
            // 处理返回值
            if (recv_len < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                    break;
                else if (errno == EINTR)
                    continue;
                else
                {
                    // 真出错了
                    LogModule::LOG(FATAL) << "recv error";
                    HandleExcepter();
                    return;
                }
            }
            else if (recv_len == 0)
            {
                HandleExcepter();
                return;
            }
            else
            {
                buffer[recv_len] = 0;
                _in_buffer += buffer;
            }
        }

        LogModule::LOG(DEBUG) << "Channel: inbuffer:\n"
                              << _in_buffer;

        if (!_in_buffer.empty())
            _out_buffer += _handler(_in_buffer);
        if (!_out_buffer.empty())
            HandleWrite();
    }
    void HandleWrite() override
    {
        // 一直发送
        while (true)
        {
            ssize_t send_len = ::send(_sockfd, _out_buffer.c_str(), _out_buffer.length(), 0);
            if (send_len < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                    break;
                if (errno == EINTR)
                    continue;
                else
                {
                    HandleExcepter();
                    break;
                }
            }
            else if (send_len == 0)
            {
                break;
            }
            else
            {
                _out_buffer.erase(0, send_len);
                if (_out_buffer.empty())
                    break;
            }
        }
        // 走到这里发生了什么？
        // 1.数据发送完了
        // 2.阻塞了或者被中断了
        // Epoll模式只读一次，下一次在读需要等待再次发送数据

        if (!_out_buffer.empty())
        {
            // 添加一次对写事件的关心，EPoll就会工作一次
            // 读事件常设，写事件需要时在关心
            GetOwner()->EnableReadWrite(_sockfd, true, true);
        }
        else
        {
            GetOwner()->EnableReadWrite(_sockfd, true, false);
        }
    }
    void HandleExcepter() override
    {
        GetOwner()->DelConnection(_sockfd);
    }
    int GetSockFd() const override
    {
        return _sockfd;
    }

    std::string &Inbuffer()
    {
        return _in_buffer;
    }
    void AppendOutBuffer(const std::string &out)
    {
        _out_buffer += out;
    }
    ~Channel() {}

private:
    int _sockfd;
    // 读写缓冲区
    std::string _in_buffer;
    std::string _out_buffer;
    // 客户端地址
    InetAddr _client_addr;
    // 回指指针
    // std::unique_ptr<Reactor> _owner;
};

#endif // CHANNEL_HPP